﻿/// File: ViewletControls\textbox.fs
/// 
/// Author: Giacomo Righetti (righetti@di.unipi.it)
///   
/// ------------------------------------------------------------
/// Copyright (c) Microsoft Corporation.  All rights reserved.
/// 
/// The use and distribution terms for this software are 
/// contained in the file named license.txt, which can be found 
/// in the root of this distribution.
/// By using this software in any fashion, you are agreeing to 
/// be bound by the terms of this license.
///
/// You must not remove this notice, or any other, from this
/// software.
/// ------------------------------------------------------------

namespace LightweightControls

open System
open System.Text
open System.Drawing
open System.Windows.Forms
open System.Windows.Forms.VisualStyles

///
/// Summary:
///     The lightweight version of the text box control.
type LightweightTextBox() as x =
    inherit LightweightControl()
    
    let timer : Timer = new Timer()
    let mutable showCaret = false
    let text : StringBuilder = new StringBuilder()
    let mutable posInText = 0
    let mutable toUpper = false
    let mutable insertMode = false
    
    do
        timer.Interval <- 800
        timer.Tick.Add(fun _ -> showCaret <- not showCaret) //; x.Invalidate())
        timer.Start()
    
    override x.OnMouseDown (e) = 
        // in base a dove si è cliccato con il mouse è necessario modificare la posizione del caret
        ()

    override x.OnKeyDown (e) =
        // se shift -> left,up allarga la selezione a sx | right,down sposta la selezione a destra
        // se control -> left,up spostano all'estremo sx | right,down spostano all'estremo destro
     
        if e.KeyCode = Keys.Insert then insertMode <- not insertMode
        
        toUpper <- e.KeyCode = Keys.LShiftKey || e.KeyCode = Keys.RShiftKey || e.KeyCode = Keys.CapsLock
        
        if e.KeyCode = Keys.End then 
            posInText <- text.Length
        elif e.KeyCode = Keys.Home then
            posInText <- 0
        elif e.KeyCode = Keys.Left then
            posInText <- posInText - 1    
        else 
            posInText <- posInText + 1      
                        
        (match e.KeyCode with
        | Keys.Space -> text.Append(' ')
        | Keys.Back -> text.Remove(text.Length - 1, 1)
        | Keys.Cancel -> text.Remove(posInText, 1)
        | Keys.NumPad0 | Keys.D0 -> text.Append('0')
        | Keys.NumPad1 | Keys.D1 -> text.Append('1')
        | Keys.NumPad2 | Keys.D2 -> text.Append('2')
        | Keys.NumPad3 | Keys.D3 -> text.Append('3')
        | Keys.NumPad4 | Keys.D4 -> text.Append('4')
        | Keys.NumPad5 | Keys.D5 -> text.Append('5')
        | Keys.NumPad6 | Keys.D6 -> text.Append('6')
        | Keys.NumPad7 | Keys.D7 -> text.Append('7')
        | Keys.NumPad8 | Keys.D8 -> text.Append('8')
        | Keys.NumPad9 | Keys.D9 -> text.Append('9')
        | Keys.Add -> text.Append('+')
        | Keys.Divide -> text.Append('/')
        | Keys.Multiply -> text.Append('*')
        | Keys.Subtract -> text.Append('-')
        | Keys.Tab -> text.Append('\t')
        | key when e.Modifiers = Keys.None ->
            let toAdd = if toUpper then e.KeyCode.ToString() else e.KeyCode.ToString().ToLower()
            text.Append(toAdd)
        | _ -> failwith "error") |> ignore
        
        x.Invalidate()

    override x.OnPaint (e) = 
        let g = e.Graphics
        //TextBoxRenderer.DrawTextBox(g, x.ClientRectangle, TextBoxState.Normal)
        
        let textSize = g.MeasureString(text.ToString(), x.Font)
        
        if showCaret then
            g.DrawLine(Pens.Black, textSize.Width - 1.0f, 1.0f, textSize.Width - 1.0f, textSize.Height - 1.0f)
            g.DrawString(text.ToString(), x.Font, Brushes.Black, PointF.Empty)